<template>
    <div>
        <el-row :gutter="20">
            <!-- 树形数据展示 -->
            <el-col :span="4">
                <el-row class="tree-row">
                    <el-col :span="24">
                        <el-input v-model="filterText" :prefix-icon="Search" clearable placeholder="请输入部门名称" />
                        <el-tree ref="treeRef" class="filter-tree" :data="treeData" :props="defaultProps"
                            default-expand-all node-key="deptId" :filter-node-method="filterNode"
                            :expand-on-click-node="false" @node-click="handleNodeClick" />
                    </el-col>
                </el-row>
            </el-col>
            <!-- 主体内容展示 -->
            <el-col :span="20">
                <!-- 搜索参数组件 -->
                <el-form :model="params">
                    <el-row :gutter="20">
                        <el-col :span="7">
                            <el-form-item label="用户名称" class="bold-label">
                                <el-input v-model="params.username" placeholder="请输入用户名称" clearable />
                            </el-form-item>
                        </el-col>
                        <el-col :span="7">
                            <el-form-item label="手机号码" class="bold-label">
                                <el-input v-model="params.phone" placeholder="请输入手机号码" clearable />
                            </el-form-item>
                        </el-col>
                        <el-col :span="7">
                            <el-form-item label="状态" class="bold-label">
                                <el-select v-model="params.status" placeholder="用户状态">
                                    <el-option label="启用" value="0"></el-option>
                                    <el-option label="禁用" value="1"></el-option>
                                </el-select>
                            </el-form-item>
                        </el-col>
                    </el-row>

                    <el-row :gutter="20">
                        <el-col :span="9">
                            <el-form-item label="创建时间" class="bold-label">
                                <el-date-picker v-model="dataTime" value-format="YYYY-MM-DD" type="datetimerange"
                                    start-placeholder="开始时间" end-placeholder="结束时间" @change="handleDateChange" />
                            </el-form-item>
                        </el-col>
                        <el-col :span="6">
                            <el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button>
                            <el-button :icon="Refresh" @click="resetField">重置</el-button>
                        </el-col>
                    </el-row>
                </el-form>
                <!-- 搜索参数组件结束 -->

                <!-- 按钮组件 -->
                <el-row style="margin-bottom: 10px;">
                    <el-col :span="12">
                        <div>
                            <el-button type="primary" plain :icon="Plus" @click="openUser">新增</el-button>
                            <el-button type="success" plain :disabled="updateDisabled" :icon="EditPen"
                                @click="openUpdateUser">修改</el-button>
                            <el-button type="danger" plain :disabled="deleteDisabled" :icon="Delete"
                                @click="handleDelete">删除</el-button>
                            <el-button type="info" plain :icon="Upload">导入</el-button>
                            <el-button type="warning" plain :icon="Download">导出</el-button>
                        </div>
                    </el-col>
                    <el-col :span="12">
                        <div class="button-right">
                            <el-tooltip content="隐藏搜索" placement="top">
                                <el-button :icon="Search" circle />
                            </el-tooltip>
                            <el-tooltip content="刷新" placement="top">
                                <el-button :icon="Refresh" circle @click="refresh" />
                            </el-tooltip>
                        </div>
                    </el-col>
                </el-row>
                <!--按钮组件结束  -->

                <!-- 表格组件 -->
                <el-row>
                    <el-table :data="tableData" style="width: 100%" @selection-change="handleSelectionChange">
                        <el-table-column align="center" type="selection" :selectable="selectable" width="40" />
                        <el-table-column align="center" label="用户编号" property="userId" />
                        <el-table-column align="center" property="userName" label="用户名称" />
                        <el-table-column align="center" property="nickName" label="用户昵称" />
                        <el-table-column align="center" property="dept.deptName" label="部门" width="200" />
                        <el-table-column align="center" property="phone" label="手机号码" width="120" />
                        <el-table-column align="center" property="status" label="状态" width="55">
                            <template #default="scope">
                                <el-switch v-model="scope.row.status" active-value="0" inactive-value="1"
                                    @change="handleStatusChange(scope.row.status, scope.row)">
                                </el-switch>
                            </template>
                        </el-table-column>
                        <el-table-column align="center" property="createTime" label="创建时间" width="200" />
                        <el-table-column align="center" label="操作" width="180">
                            <template #default="scope">
                                <div class="button-group">
                                    <el-button class="el-button-mini" link type="primary" size="small" :icon="EditPen"
                                        @click="updateRow(scope.$index, scope.row)">修改</el-button>
                                    <el-button class="el-button-mini" link type="primary" size="small" :icon="Delete"
                                        @click="deleteRow(scope.$index, scope.row)">删除</el-button>

                                    <el-dropdown @command="(command) => handleCommand(command, scope.row)">
                                        <el-button class="el-button-mini" link type="primary" size="small"
                                            :icon="DArrowRight">更多</el-button>
                                        <template #dropdown>
                                            <el-dropdown-menu>
                                                <el-dropdown-item command="resetPassword">重置密码</el-dropdown-item>
                                            </el-dropdown-menu>
                                        </template>
                                    </el-dropdown>
                                </div>
                            </template>
                        </el-table-column>
                    </el-table>
                </el-row>
                <!-- 表格组件结束 -->
                <!-- 分页组件 -->
                <el-row>
                    <el-col :span="24">
                        <div class="demo-pagination-block">
                            <el-pagination v-model:current-page="params.currentPage" v-model:page-size="params.pageSize"
                                background :default-page-size="params.pageSize" :page-sizes="pageSizes"
                                layout="total,sizes,prev,pager,next,jumper" :total="parseInt(pageResult.total)"
                                @size-change="handleSizeChange" @current-change="handleCurrentChange">
                            </el-pagination>
                        </div>
                    </el-col>
                </el-row>
                <!-- 分页组件结束 -->

                <!-- 弹窗组件 -->
                <el-dialog :title="title" v-model="dialogVisible" @close="handleClose" draggable @open="handleOpen">
                    <!-- 表单数据项 -->
                    <el-form :model="userForm.user" ref="userFroms" :rules="userRules">
                        <el-row :gutter="20">
                            <el-col :span="12">
                                <el-form-item label="用户昵称" class="bold-label" prop="nickName">
                                    <el-input v-model="userForm.user.nickName" clearable
                                        placeholder="请输入用户昵称"></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="归属部门" class="bold-label" prop="deptId">
                                    <el-tree-select v-model="userForm.user.deptId" :data="treeFormData"
                                        :props="defaultProps" placeholder="请选择归属部门"></el-tree-select>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="20">
                            <el-col :span="12">
                                <el-form-item label="手机号码" class="bold-label" prop="phone">
                                    <el-input v-model="userForm.user.phone" clearable placeholder="请输入手机号码"></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="11" :offset="1">
                                <el-form-item label="邮箱" class="bold-label" prop="email">
                                    <el-input v-model="userForm.user.email" clearable placeholder="请输入邮箱"></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="20">
                            <el-col :span="12" v-if="title != '修改用户'">
                                <el-form-item label="用户名称" class="bold-label" prop="userName">
                                    <el-input v-model="userForm.user.userName" clearable
                                        placeholder="请输入用户名称"></el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12" v-if="title != '修改用户'">
                                <el-form-item label="用户密码" class="bold-label" prop="password">
                                    <el-input v-model="userForm.user.password" clearable placeholder="请输入用户密码"
                                        type="password" show-password></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row :gutter="20">
                            <el-col :span="12">
                                <el-form-item label="用户性别" class="bold-label">
                                    <el-select v-model="userForm.user.sex" placeholder="请选择性别">
                                        <el-option label="男" value="男"></el-option>
                                        <el-option label="女" value="女"></el-option>
                                        <el-option label="未知" value=""></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                            <el-col :span="11" :offset="1">
                                <el-form-item label="状态" class="bold-label">
                                    <el-radio-group v-model="userForm.user.status">
                                        <el-radio value="0">正常</el-radio>
                                        <el-radio value="1">停用</el-radio>
                                    </el-radio-group>
                                </el-form-item>
                            </el-col>
                        </el-row>

                        <el-row :gutter="20">
                            <el-col :span="11" :offset="1">
                                <el-form-item label="岗位" class="bold-label">
                                    <el-select v-model="userForm.postIds" placeholder="请选择岗位" multiple>
                                        <el-option v-if="postRoleData.postIds != null"
                                            v-for="item in postRoleData.postIds" :key="item.postId"
                                            :disabled="item.status === '1'" :label="item.postName"
                                            :value="item.postId"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                            <el-col :span="11" :offset="1">
                                <el-form-item label="角色" class="bold-label">
                                    <el-select v-model="userForm.roleIds" placeholder="请选择角色" multiple>
                                        <el-option v-if="postRoleData.roleIds != null"
                                            v-for="item in postRoleData.roleIds" :key="item.roleId"
                                            :disabled="item.status === '1'" :label="item.roleName"
                                            :value="item.roleId"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="23" :offset="1">
                                <el-form-item label="备注" class="bold-label">
                                    <el-input v-model="userForm.user.remark" clearable placeholder="请输入备注"></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                    </el-form>
                    <template #footer>
                        <div>
                            <el-button type="primary" @click="handleSubmit(userFroms)">
                                确定
                            </el-button>
                            <el-button @click="dialogVisible = false">取消</el-button>
                        </div>
                    </template>
                </el-dialog>
                <!-- 弹窗组件结束 -->

                <!-- 重置密码对话框 -->
                <el-dialog v-model="dialogVisiblePassword" title="提示" width="30%">
                    <span>请输入 "{{ selectedRow?.userName }}" 的新密码</span>
                    <el-input v-model="newPassword" placeholder="请输入新密码"></el-input>
                    <template #footer>
                        <span class="dialog-footer">
                            <el-button @click="dialogVisiblePassword = false">取消</el-button>
                            <el-button type="primary" @click="confirmResetPassword">确定</el-button>
                        </span>
                    </template>
                </el-dialog>
            </el-col>
        </el-row>
    </div>
</template>

<script setup>
import { Search, Refresh, Delete, Plus, EditPen, Download, Upload, DArrowRight } from '@element-plus/icons-vue'
import { onMounted, ref, watch, reactive, nextTick } from 'vue'
import { findDeptTree, findByDept, updateUserStatus, deleteUserByDept, findPostRole, insertUser, findUserById, updateUser, updatePassword } from '@/apis/index'
import { ElMessageBox, ElMessage } from 'element-plus'
const treeRef = ref(null) // 树形组件
const filterText = ref('') // 过滤输入框
const treeData = ref([]) // 树形数据
const pageResult = ref({}) // 表格分页数据
const pageSizes = [2, 5, 8, 10] // 分页大小
const tableData = ref([])   // 表格数据
const dataTime = ref([]) // 日期数组
const deleteDisabled = ref(true) // 控制删除按钮是否禁用
const updateDisabled = ref(true) // 控制修改按钮是否禁用
const userIds = ref([]) // 选中行的用户id数组 删除时使用
const title = ref('') // 弹窗标题
const dialogVisible = ref(false) // 弹窗显示状态
const treeFormData = ref([]) // 部门树表单数据
const postRoleData = ref({}) // 岗位角色数据
const dialogVisiblePassword = ref(false);//重置密码弹窗
let selectedRow = ref(null);
const newPassword = ref('');

// 弹窗表单数据
const userForm = ref({
    user: {
        nickName: '',
        deptId: '',
        phone: '',
        email: '',
        userName: '',
        password: '123456',
        sex: '',
        status: "0",
        remark: ''
    },
    postIds: [],
    roleIds: [],
});
/**
 * 处理点击树形查询数据
 * @param data 树形数据
 * @param node 
 * @param vnode 
 * @param event 
 */
const handleNodeClick = async (data, node, vnode, event) => {
    params.value.deptId = node.data.deptId
    handleSearch()
}
//属性的映射关系
const defaultProps = {
    children: 'children',
    label: 'deptName',
    value: 'deptId'
}
// 查询参数
const params = ref({
    currentPage: 1,
    pageSize: 5,
    username: '',
    phone: '',
    status: '',
    startTime: '',
    endTime: '',
    deptId: ''
})

/**
 * 用户确认选定的值时触发
 * @param val 日期数组
 */
const handleDateChange = (val) => {
    if (val) {
        params.value.startTime = val[0]
        params.value.endTime = val[1]
    } else {
        // 清空参数中的日期
        params.value.startTime = ''
        params.value.endTime = ''
    }
}

onMounted(async () => {
    treeData.value = await findDeptTree() // 获取部门树数据
    pageResult.value = await findByDept(params.value) // 获取分页数据
    tableData.value = pageResult.value.records // 获取表格数据
    console.log(treeData.value)
})
// 监测文本值变化
watch(filterText, (val) => {
    if (treeRef.value) {
        treeRef.value.filter(val)
    }
})
// 过滤字段
const filterNode = (value, data) => {
    if (!value) return true
    return (data.deptName || '').includes(value)
}
// 参数搜索查询数据
const handleSearch = async () => {
    // console.log(params.value)
    pageResult.value = await findByDept(params.value)
    tableData.value = pageResult.value.records
}
//刷新
const refresh = async () => {
    await handleSearch();
}

/**
 * 处理当前页码变化
 * @param currentPage 当前页码
 */
const handleCurrentChange = async (currentPage) => {
    params.value.currentPage = currentPage
    await handleSearch() // 数据刷新
}
/**
 * 处理分页大小变化
 * @param size 分页大小
 */
const handleSizeChange = async (size) => {
    params.value.pageSize = size
    await handleSearch() // 数据刷新
}

// 重置参数
function resetField() {
    params.value = {
        currentPage: 1,
        pageSize: 2,
        username: '',
        phone: '',
        status: '',
        startTime: '',
        endTime: '',
        deptId: ''
    }
    //重置时间参数
    dataTime.value = []
    handleSearch() // 数据刷新
}

// 开关按钮状态
const handleStatusChange = (val, row) => {
    if (row.isRoot != null) {
        ElMessage.error('不允许操作超级管理员用户')
        row.status = row.status == "0" ? "1" : "0"
        return
    }
    ElMessageBox.confirm(
        `确认要${val === "0" ? '“启用”' : '“禁用”'}“${row.userName}”用户吗?`,
        '系统提示',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        }
    ).then(async () => {
        await updateUserStatus({ userId: row.userId, status: val })
        await handleSearch() // 数据刷新
        ElMessage.success('修改成功')
    }).catch(() => {
        row.status = row.status == "0" ? "1" : "0"
    })
}
// 使用条件选中行数据
const selectable = (row) => {
    return row.isRoot == null // 只能选择不是最高管理员的行数据
}
//修改用户信息
const updateRow = async (index, row) => {
    if (row.isRoot != null) {
        ElMessage.error("不允许操作超级管理员用户")
        return;
    }
    userForm.value.user.deptId = row.dept.deptId
    userForm.value.user.userId = row.userId
    await openUpdateUser()
}

// 重置密码处理命令
const handleCommand = (command, row) => {
    if (command === 'resetPassword' && row) {
        resetPassword(row);
    }
}

const resetPassword = (row) => {
    // 检查 row 是否为 null 或 undefined
    if (!row) {
        ElMessage.error("未选中任何行");
        return;
    }
    console.log(row)
    if (row.isRoot != null) {
        ElMessage.warning("不允许操作超级管理员用户");
        return;
    }

    dialogVisiblePassword.value = true;
    selectedRow.value = row;
};

const confirmResetPassword = async () => {
    const row = selectedRow.value;

    if (!row || !newPassword.value) {
        ElMessage.error("请选择一行并输入新密码");
        return;
    }

    try {
        await updatePassword({ userId: row.userId, password: newPassword.value });
        ElMessage.success("密码重置成功");
        dialogVisiblePassword.value = false;
        newPassword.value = '';
    } catch (error) {
        ElMessage.error("密码重置失败：" + error.message);
    }
};

/**
 * 删除单行用户数据
 * @param index 行索引
 * @param row 行数据
 */
const deleteRow = async (index, row) => {
    if (row.isRoot != null) {
        ElMessage.error('不允许操作超级管理员用户')
        return
    }
    ElMessageBox.confirm(`是否确认删除用户编号为"${row.userId}"的数据项？`, '系统提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
    }).then(async () => {
        userIds.value.push(row.userId)
        await deleteUserByDept(userIds.value)
        await handleSearch() // 数据刷新
        ElMessage.success('删除成功')
    }).catch(() => {
        // ElMessage.info("取消删除");
    })
}

/**
 * 处理选中行变化
 * @param val 选中行的数组
 */
const handleSelectionChange = (val) => {
    deleteDisabled.value = !val.length
    updateDisabled.value = !(val.length === 1)
    if (!updateDisabled.value) {
        userForm.value.user.deptId = val[0].dept.deptId
        userForm.value.user.userId = val[0].userId
        console.log(val)
    } else {
        resetForm()
    }
    // 使用map方法过滤出选中行的目标id数组
    userIds.value = val.map(item => item.userId)
}

const userFroms = ref();
const fromUser = reactive({ ...userForm });
const userRules = {
    nickName: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
    deptId: [{ required: true, message: "归属部门不能为空", trigger: "blur" }],
    userName: [{ required: true, message: "用户名称不能为空", trigger: "blur" }],
    password: [{ required: true, message: "用户密码不能为空", trigger: "blur" }],
};

const openUser = async () => {
    title.value = '添加用户'
    dialogVisible.value = !dialogVisible.value
    treeFormData.value = [...treeData.value]
}

const openUpdateUser = async () => {
    title.value = '修改用户'
    dialogVisible.value = !dialogVisible.value
    treeFormData.value = [...treeData.value]
    const vo = await findUserById(userForm.value.user.userId)
    userForm.value.user = { ...vo.sysUser, deptId: vo.sysUser.dept.deptId }
    postRoleData.value.postIds = vo.postIds
    postRoleData.value.roleIds = vo.roleIds
    userForm.value.postIds = vo.ownPostIds
    userForm.value.roleIds = vo.ownRoleIds
    console.log(vo)
}
/**
 * 点击删除多条用户数据
 */
const handleDelete = async () => {
    await deleteUserByDept(userIds.value)
    await handleSearch() // 数据刷新
    ElMessage.success('删除成功')
}
/**
 * 表单提交数据
 */
const handleSubmit = (value) => {
    if (!value) return;
    value.validate(valid => {
        if (valid && userForm.value.postIds.length != 0 && userForm.value.roleIds.length != 0) {
            if (title.value === '添加用户') {
                insertUser(userForm.value).then(async () => {
                    ElMessage.success("新增成功");
                    await handleSearch() // 数据刷新
                    resetForm() //重置表单数据
                })
            } else if (title.value === '修改用户') {
                updateUser(userForm.value).then(async () => {
                    ElMessage.success("修改成功");
                    await handleSearch() // 数据刷新
                })
            }
            console.log("即将更新的数据：", userForm.value)
            dialogVisible.value = !dialogVisible.value
            // ElMessage.success(`${title.value}成功`)
        } else {
            ElMessage.error("请选择岗位和角色，再提交！");
            console.log("请根据提示完整表单数据！");
        }
    })
}
const handleClose = () => {
    dialogVisible.value = false
    resetForm() // 表单数据清空
}
// 弹窗打开时获取岗位角色数据
const handleOpen = async () => {
    postRoleData.value = await findPostRole() // 获取岗位角色数据
    // console.log(postRoleData.value)
    nextTick(() => {
        userFroms.value.clearValidate();//清空校验
    })
}
/**
 * 清空表单数据
 */
const resetForm = () => {
    userForm.value = {
        user: { status: "0", password: '123456' },
        postIds: [],
        roleIds: []
    } //用户表单清空
    treeFormData.value = [] //表单部门树清空
    title.value = '' //弹窗标题清空
}
</script>

<style scoped>
.bold-label {
    font-weight: bold;
}

.button-right {
    text-align: right;
}

.button-group {
    display: flex;
    justify-content: center;
    align-items: center;
}

.demo-pagination-block .el-pagination {
    justify-content: end;
    margin-top: 20px;
}

.tree-row:deep(.el-tree) {
    background: #f0f2f5;
}

:deep(.el-button-mini) {
    margin: 0;
}

.bold-label {
    font-weight: bold;
}
</style>
